package com.itheima.aop;

import com.alibaba.fastjson.JSON;
import com.itheima.common.JwtUtils;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import io.jsonwebtoken.Claims;

import java.time.LocalDateTime;
import javax.servlet.http.HttpServletRequest;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Aspect
@Component
@Slf4j
public class SyslogAspect {

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Pointcut("@annotation(com.itheima.annotation.Syslog)")
    public void pt() {

    }

    @Around("pt()")
    public Object record(ProceedingJoinPoint joinPoint) throws Throwable {

        String token = httpServletRequest.getHeader("token");
        Claims claims = JwtUtils.parseJWT(token);
        // 操作人
        Integer id = claims.get("id", Integer.class);
        // 全类名
        String fullClassName = joinPoint.getSignature().getDeclaringTypeName();
        // 得到方法名
        String methodName = joinPoint.getSignature().getName();
        // 方法运行时参数
        Object[] args = joinPoint.getArgs();
        long start = System.currentTimeMillis();
        // 操作时间
        LocalDateTime operateTime = LocalDateTime.now();
        // 返回值
        Object proceed = joinPoint.proceed();
        long end = System.currentTimeMillis();
        // 操作耗时
        long time = end - start;

        OperateLog operateLog = new OperateLog();
        operateLog.setOperateUser(id);
        operateLog.setOperateTime(operateTime);
        operateLog.setClassName(fullClassName);
        operateLog.setMethodName(methodName);
        operateLog.setMethodParams(JSON.toJSONString(args));
        operateLog.setReturnValue(JSON.toJSONString(proceed));
        operateLog.setCostTime(time);
        operateLogMapper.insert(operateLog);

        return proceed;


    }

}
